namespace C1.Win.C1FlexGrid.Util.BaseControls
{
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    public abstract class ScrollableControl : Control
    {
        protected BorderStyleEnum _borderStyle;
        protected int _borderWidth;
        protected bool _fireOnScroll;
        protected HScrollBar _hScrollBar;
        protected bool _sbHorz;
        protected bool _sbVert;
        protected System.Windows.Forms.ScrollBars _scrollBars;
        protected Size _scrollSize;
        private int _tickLast = -1;
        protected bool _track;
        protected Cursor _userCursor;
        protected VScrollBar _vScrollBar = new VScrollBar();

        public ScrollableControl()
        {
            this._vScrollBar.SmallChange = 10;
            this._vScrollBar.ValueChanged += new EventHandler(this._vScrollBar_ValueChanged);
            this._hScrollBar = new HScrollBar();
            this._hScrollBar.SmallChange = 10;
            this._hScrollBar.ValueChanged += new EventHandler(this._hScrollBar_ValueChanged);
            base.Controls.Add(this._vScrollBar);
            base.Controls.Add(this._hScrollBar);
            this._userCursor = Cursors.Default;
            this._borderStyle = BorderStyleEnum.Fixed3D;
            this._borderWidth = 1;
            this.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.ScrollSize = new Size(0, 0);
            this.ScrollTrack = true;
            this.UpdateScrollbars();
        }

        private void _hScrollBar_ValueChanged(object sender, EventArgs e)
        {
            if (this._fireOnScroll)
            {
                this.OnScroll(System.Windows.Forms.ScrollBars.Horizontal);
            }
        }

        private void _vScrollBar_ValueChanged(object sender, EventArgs e)
        {
            if (this._fireOnScroll)
            {
                this.OnScroll(System.Windows.Forms.ScrollBars.Vertical);
            }
        }

        private int CheckScrollBarValue(int val, ScrollBar sb, int szview, int szdoc)
        {
            if ((szview < 0) || (szview > szdoc))
            {
                return 0;
            }
            if (val > sb.Maximum)
            {
                val = sb.Maximum;
            }
            if (val > (szdoc - szview))
            {
                val = szdoc - szview;
            }
            if (val < sb.Minimum)
            {
                val = sb.Minimum;
            }
            return val;
        }

        protected void DrawBorders(PaintEventArgs e)
        {
            Rectangle rectangle;
            Graphics g = e.Graphics;
            if (this._sbHorz && this._sbVert)
            {
                rectangle = new Rectangle(this._hScrollBar.Right, this._vScrollBar.Bottom, this._vScrollBar.Width, this._hScrollBar.Height);
                g.FillRectangle(SystemBrushes.Control, rectangle);
            }
            if (this._borderStyle != BorderStyleEnum.None)
            {
                rectangle = new Rectangle(0, 0, base.Width - 1, base.Height - 1);
                g.DrawRectangle(SystemPens.WindowFrame, rectangle);
            }
            this.SetClip(g, this.ClientRectangle);
        }

        protected void ExcludeClip(Graphics g, Rectangle rc)
        {
            Region clip = g.Clip;
            if (clip.IsEmpty(g) || clip.IsInfinite(g))
            {
                clip = new Region(base.ClientRectangle);
            }
            clip.Exclude(rc);
            g.Clip = clip;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            int tickCount = Environment.TickCount;
            if (this._tickLast > 0)
            {
                int num2 = tickCount - this._tickLast;
                if (num2 < SystemInformation.DoubleClickTime)
                {
                    this._tickLast = -1;
                    return;
                }
            }
            this._tickLast = tickCount;
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.None)
            {
                Point point = new Point(e.X, e.Y);
                if (!this.ClientRectangle.Contains(point.X, point.Y))
                {
                    return;
                }
            }
            base.OnMouseMove(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            this.DrawBorders(e);
            base.OnPaint(e);
        }

        protected override void OnResize(EventArgs e)
        {
            this.UpdateScrollbars();
            base.OnResize(e);
        }

        protected virtual void OnScroll(System.Windows.Forms.ScrollBars sb)
        {
            base.Invalidate();
        }

        protected virtual void OnScrollTip(int newValue)
        {
        }

        protected void SetClip(Graphics g, Rectangle rc)
        {
            g.Clip = new Region(rc);
        }

        public bool ShouldSerializeBorderStyle()
        {
            return (this.BorderStyle != BorderStyleEnum.Fixed3D);
        }

        public bool ShouldSerializeScrollBars()
        {
            return (this.ScrollBars != System.Windows.Forms.ScrollBars.Both);
        }

        private void UpdateScrollbar(ScrollBar sb, int szview, int szdoc)
        {
            if (szview >= 0)
            {
                if (szview >= szdoc)
                {
                    sb.Maximum = sb.Minimum = sb.Value = 0;
                }
                else
                {
                    sb.Maximum = szdoc - 1;
                    sb.Minimum = 0;
                    sb.LargeChange = szview;
                    int num = szdoc - szview;
                    if ((num > 0) && (sb.Value > num))
                    {
                        sb.Value = num;
                    }
                    if (sb.Value < 0)
                    {
                        sb.Value = 0;
                    }
                }
            }
        }

        protected virtual void UpdateScrollbars()
        {
            Rectangle clientRectangle = base.ClientRectangle;
            Rectangle rectangle2 = clientRectangle;
            rectangle2.Width -= this._vScrollBar.Width + (this._borderWidth * 2);
            rectangle2.Height -= this._hScrollBar.Height + (this._borderWidth * 2);
            this._sbHorz = this._sbVert = false;
            if (this._scrollSize.Height > clientRectangle.Height)
            {
                this._sbVert = true;
            }
            if (this._scrollSize.Width > clientRectangle.Width)
            {
                this._sbHorz = true;
            }
            if ((!this._sbHorz && this._sbVert) && (this._scrollSize.Width > rectangle2.Width))
            {
                this._sbHorz = true;
            }
            if ((this._sbHorz && !this._sbVert) && (this._scrollSize.Height > rectangle2.Height))
            {
                this._sbVert = true;
            }
            switch (this._scrollBars)
            {
                case System.Windows.Forms.ScrollBars.None:
                    this._sbVert = this._sbHorz = false;
                    break;

                case System.Windows.Forms.ScrollBars.Horizontal:
                    this._sbVert = false;
                    break;

                case System.Windows.Forms.ScrollBars.Vertical:
                    this._sbHorz = false;
                    break;
            }
            this._hScrollBar.Visible = this._sbHorz;
            this._vScrollBar.Visible = this._sbVert;
            this._vScrollBar.Top = 0;
            this._vScrollBar.Left = clientRectangle.Right - this._vScrollBar.Width;
            this._vScrollBar.Height = this._sbHorz ? (clientRectangle.Height - this._hScrollBar.Height) : clientRectangle.Height;
            this._hScrollBar.Left = 0;
            this._hScrollBar.Top = clientRectangle.Bottom - this._hScrollBar.Height;
            this._hScrollBar.Width = this._sbVert ? (clientRectangle.Width - this._vScrollBar.Width) : clientRectangle.Width;
            clientRectangle = this.ClientRectangle;
            this.UpdateScrollbar(this._hScrollBar, clientRectangle.Width, this._scrollSize.Width);
            this.UpdateScrollbar(this._vScrollBar, clientRectangle.Height, this._scrollSize.Height);
            this._fireOnScroll = true;
            base.Invalidate();
        }

        public BorderStyleEnum BorderStyle
        {
            get
            {
                return this._borderStyle;
            }
            set
            {
                if (this._borderStyle != value)
                {
                    this._borderStyle = value;
                    this._borderWidth = (value == BorderStyleEnum.None) ? 0 : 1;
                    this.UpdateScrollbars();
                }
            }
        }

        public Rectangle ClientRectangle
        {
            get
            {
                Rectangle clientRectangle = base.ClientRectangle;
                clientRectangle.Inflate(-this._borderWidth, -this._borderWidth);
                if (this._sbHorz)
                {
                    clientRectangle.Height -= this._hScrollBar.Height - 1;
                }
                if (this._sbVert)
                {
                    clientRectangle.Width -= this._vScrollBar.Width - 1;
                }
                return clientRectangle;
            }
        }

        internal bool DesignMode
        {
            get
            {
                return ((this.Site != null) && this.Site.DesignMode);
            }
        }

        internal HScrollBar ScrollBarHorz
        {
            get
            {
                return this._hScrollBar;
            }
        }

        public System.Windows.Forms.ScrollBars ScrollBars
        {
            get
            {
                return this._scrollBars;
            }
            set
            {
                if (this._scrollBars != value)
                {
                    this._scrollBars = value;
                    Point scrollPosition = this.ScrollPosition;
                    switch (this._scrollBars)
                    {
                        case System.Windows.Forms.ScrollBars.None:
                            scrollPosition.X = 0;
                            scrollPosition.Y = 0;
                            break;

                        case System.Windows.Forms.ScrollBars.Horizontal:
                            scrollPosition.Y = 0;
                            break;

                        case System.Windows.Forms.ScrollBars.Vertical:
                            scrollPosition.X = 0;
                            break;
                    }
                    this.ScrollPosition = scrollPosition;
                    this.UpdateScrollbars();
                }
            }
        }

        internal VScrollBar ScrollBarVert
        {
            get
            {
                return this._vScrollBar;
            }
        }

        public Point ScrollPosition
        {
            get
            {
                return new Point(-this._hScrollBar.Value, -this._vScrollBar.Value);
            }
            set
            {
                Point point = value;
                Rectangle clientRectangle = this.ClientRectangle;
                int num = this.CheckScrollBarValue(-point.X, this._hScrollBar, clientRectangle.Width, this._scrollSize.Width);
                int num2 = this.CheckScrollBarValue(-point.Y, this._vScrollBar, clientRectangle.Height, this._scrollSize.Height);
                if ((this._hScrollBar.Value != num) || (this._vScrollBar.Value != num2))
                {
                    bool flag = this._fireOnScroll;
                    this._fireOnScroll = true;
                    if (this._hScrollBar.Value != num)
                    {
                        this._hScrollBar.Value = num;
                    }
                    if (this._vScrollBar.Value != num2)
                    {
                        this._vScrollBar.Value = num2;
                    }
                    this._fireOnScroll = flag;
                    this.UpdateScrollbars();
                }
            }
        }

        internal Size ScrollSize
        {
            get
            {
                return this._scrollSize;
            }
            set
            {
                this._scrollSize = value;
                this.UpdateScrollbars();
            }
        }

        public bool ScrollTrack
        {
            get
            {
                return this._track;
            }
            set
            {
                this._track = value;
            }
        }
    }
}

